package com.zzyl.nursing.service.impl;

import java.util.List;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.AgeCalculator;
import com.zzyl.common.utils.CodeGenerator;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.*;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;
/**
 * 入住管理Service业务层处理
 * 
 * @author Nan
 * @date 2025-05-24
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper,CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;

    // 注入mapper
    @Autowired
    private ElderMapper elderMapper; //老人类的mapper
    @Autowired
    private BedMapper bedMapper; // 床位的mapper
    @Autowired
    private ContractMapper contractMapper; // 合同的mapper
    @Autowired
    private CheckInConfigMapper checkInConfigMapper; // 入住配置的mapper



    /**
     * 查询入住管理
     * 
     * @param id 入住管理主键
     * @return 入住管理
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询入住管理列表
     * 
     * @param checkIn 入住管理
     * @return 入住管理
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住管理
     * 
     * @param checkIn 入住管理
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return save(checkIn)?1:0;
    }

    /**
     * 修改入住管理
     * 
     * @param checkIn 入住管理
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn)?1:0;
    }

    /**
     * 批量删除入住管理
     * 
     * @param ids 需要删除的入住管理主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids))?1:0;
    }

    /**
     * 删除入住管理信息
     * 
     * @param id 入住管理主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id)?1:0;
    }

    // 根据老人入住表的 id 查询 相关数据
    @Override
    public CheckInDetailVo seelctElderDetail(Long id) {

        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();

        // 1. 根据入住表的id 查询入住信息
        CheckIn checkIn = checkInMapper.selectCheckInById(id);

        // 2, 判断有没有入住
        if(checkIn == null){
            throw new BaseException("没有该入住信息");
        }

        // 3,根据入住表的 id 查询老人信息
        CheckInElderVo checkInElderInfo = new CheckInElderVo();

        // 4.根据入住表的 id 获取老人信息
        Elder elder = elderMapper.selectElderById(checkIn.getElderId());

        checkInElderInfo.setId(checkIn.getId());
        checkInElderInfo.setName(checkIn.getElderName());
        checkInElderInfo.setIdCardNo(checkIn.getIdCardNo());
        checkInElderInfo.setBirthday(elder.getBirthday());
        checkInElderInfo.setSex(elder.getSex());
        checkInElderInfo.setPhone(elder.getPhone());
        checkInElderInfo.setAddress(elder.getAddress());
        checkInElderInfo.setImage(elder.getImage());
        checkInElderInfo.setIdCardNationalEmblemImg(elder.getIdCardNationalEmblemImg());
        checkInElderInfo.setIdCardPortraitImg(elder.getIdCardPortraitImg());
        // 生成年龄
        // checkInElderInfo.setAge(AgeCalculator.calculateAge(elder.getBirthday()));
        checkInElderInfo.setAge(DateUtil.ageOfNow(elder.getBirthday()));
        checkInDetailVo.setCheckInElderVo(checkInElderInfo);


        //  5. 根据入住表的 id 查询 老人的家属信息
        String remark = checkIn.getRemark();
         List<ElderFamilyVo>  elderFamilyVoList= JSON.parseArray(remark, ElderFamilyVo.class);
        checkInDetailVo.setElderFamilyVoList(elderFamilyVoList);

        // 6,获取合同信息 合同表的外键 老人id

        Contract contractInfo = getContractInfo(elder.getId());

        checkInDetailVo.setContract(contractInfo);

        // 7,根据入住表的 id 查入住 配置 对应的信息
        CheckInConfigVo checkInConfigVo =  getCheckInConfig(contractInfo,id,elder);
        checkInDetailVo.setCheckInConfigVo(checkInConfigVo);


        return checkInDetailVo;
    }

    public Contract getContractInfo(Long elderId){
        LambdaQueryWrapper<Contract> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Contract::getElderId, elderId);
        return contractMapper.selectOne(queryWrapper);
    }

    public CheckInConfigVo  getCheckInConfig(Contract contract,Long id,Elder elder){

        LambdaQueryWrapper<CheckInConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CheckInConfig::getCheckInId,id);
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(queryWrapper);

        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        BeanUtils.copyProperties(checkInConfig, checkInConfigVo);
        checkInConfigVo.setStartDate(contract.getStartDate());
        checkInConfigVo.setEndDate(contract.getEndDate());
        checkInConfigVo.setBedNumber(elder.getBedNumber());


        return  checkInConfigVo;
    }

    @Override
    public void apply(CheckInApplyDto dto) {


        /* 思路：
          1. 先根据前端传来的参数，得到老人的身份证号，用老人身份证号+ 入住状态4 去 老人表中查询 是否存在 信息
          2， 如果 不存在，说明是从来 没有入住的 老人，如果查到了，说明已经入住了，给前端个提示
          3. 如果 是 没有入住的老人，更改老人 床位的状态为 已入住
          4. 如果得出了老人之前是当前没有入住过的，根据老人的 身份证号 去表里查老人信息，如果查不到说明是第1次来住的老人
             此时 要调用新增接口
             如果查到了，说明是第2次来住的老人，我们调用更新接口
          5. 新增合同信息
          6. 新增入住信息
          7. 新增入住配置信息

        ： */
        // 老人信息的dto
        CheckInElderDto elderDto = dto.getCheckInElderDto();
        //老人家属信息
        List<ElderFamilyDto> elderFamilyDtoList = dto.getElderFamilyDtoList();
        // 入住配置信息
        CheckInConfigDto checkInConfigDto = dto.getCheckInConfigDto();
        //  合同信息
        CheckInContractDto checkInContractDto = dto.getCheckInContractDto();



    //     1. 获取老人身份证号
        LambdaQueryWrapper<Elder> elderWrapper = new LambdaQueryWrapper<>();
        elderWrapper.eq(Elder::getIdCardNo,elderDto.getIdCardNo());
        elderWrapper.eq(Elder::getStatus,4); //"0=：禁用，1:启用,2=:请假,3=:退住中,4=入住中,5=已退住")

    //     从 入住信息中 查询该老人是否存在
        Elder elder = elderMapper.selectOne(elderWrapper);

        if(elder != null){
        //     此时说明老人已经入住了
            throw new BaseException("该老人已经入住了");
        }

    //     给老人分配1个 床位并更改状态,这里的床位号 要从前端传来的 dto中获取
        Long bedId = checkInConfigDto.getBedId();
    //     更改床位的状态:先得到该床位信息，然后更改
        Bed bed = bedMapper.selectBedById(bedId);
        bed.setBedStatus(1); // 床位状态: 未入住0, 已入住1 入住申请中2"

    //     更新表中的床位状态
        bedMapper.updateBed(bed);


    // 1.新增 或更新老人
        elder = saveOrUpdateElder(elderDto, bed);

    //     2. 新增合同信息
        saveContract(checkInContractDto,elder,checkInConfigDto);
    //     3. 新增入住信息：把家属信息 放在remark字段中，更新入住表

        CheckIn checkIn = saveCheckIn(elder, checkInConfigDto, elderFamilyDtoList);

        //    4，给配置表新增配置信息
        saveCheckInConfig(checkInConfigDto,checkIn);


    }



    // 新增配置信息表
   public void saveCheckInConfig(CheckInConfigDto  checkInConfigDto, CheckIn checkIn ){

        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkInConfigDto,checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
       checkInConfigMapper.insert(checkInConfig);
    }

    // 新增入住信息
    public CheckIn saveCheckIn(Elder elder,  CheckInConfigDto checkInConfigDto,   List<ElderFamilyDto> elderFamilyDtoList){

     CheckIn checkIn =   new CheckIn();

     checkIn.setElderName(elder.getName());
     checkIn.setElderId(elder.getId());
     checkIn.setIdCardNo(elder.getIdCardNo());
     checkIn.setBedNumber(elder.getBedNumber());

     checkIn.setStartDate(checkInConfigDto.getStartDate());
     checkIn.setEndDate(checkInConfigDto.getEndDate());
     checkIn.setNursingLevelName(checkInConfigDto.getNursingLevelName());

     checkIn.setStatus(0L); // 状态: 0: 已入住, 1: 已退住

     //    将家属信息 转为string
        String jsonString = JSON.toJSONString(elderFamilyDtoList);
        checkIn.setRemark(jsonString);
        checkInMapper.insert(checkIn); // 使用 mybatis-plus的方法，可以自动填充内容



     return checkIn;


    }

    // 新增合同信息
    public void saveContract(CheckInContractDto contractDto,Elder elder, CheckInConfigDto checkInConfigDto){



    //     收集合同内容
        Contract contract = new Contract();

        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        contract.setContractNumber("HT"+ CodeGenerator.generateContractNumber());

        contract.setContractName(contractDto.getContractName());
        contract.setAgreementPath(contractDto.getAgreementPath());
        contract.setThirdPartyPhone(contractDto.getThirdPartyPhone());
        contract.setThirdPartyName(contractDto.getThirdPartyName());
        contract.setStatus(1L);
        //  解约信息 暂时不考虑
        // contract.setTerminationSubmitter("");
        // contract.setTerminationDate(LocalDateTime.now());
        // contract.setTerminationAgreementPath("");
        contract.setSortOrder(0);
        contract.setStartDate(checkInConfigDto.getStartDate()); // 开始时间
        contract.setEndDate(checkInConfigDto.getEndDate()); // 结束时间
        contract.setSignDate(contractDto.getSignDate());

        contractMapper.insert(contract);





    }

    public Elder saveOrUpdateElder(CheckInElderDto elderDto,Bed bed){

    //     根据老人的身份证号查询 该老人是否在老人表中

        boolean isNew = false; // 是否是新增

       LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper();

        queryWrapper.eq(Elder::getIdCardNo,elderDto.getIdCardNo());

        Elder elder = elderMapper.selectOne(queryWrapper);



        if(elder == null){
            // 此时说明不存在老人信息，先创建1个老人对象，方便后面赋值
            isNew = true;
            elder = new Elder();
        }

        // 将参数1 中的属性 赋值到参数2上里面同样类型，同样名字的属性中
        BeanUtils.copyProperties(elderDto,elder);

        elder.setBedNumber(bed.getBedNumber());
        elder.setBedId(bed.getId());
        elder.setStatus(4);

        if(isNew){
        //     此时是新增调新增接口，这里用 mybatis-plus中的新增方法，是因为mp 中有自动填充功能
            elderMapper.insert(elder);
        } else {
        //     此时是修改 调用修改接口
            elderMapper.updateById(elder);
        }



    return elder;



    }



}
